package genetic_algorithm;

import java.util.ArrayList;

/**
 * A utility class that contains a sequence of specific genes.
 * Used by the Chromosome to split itself into chunks.
 * @author pborrego
 */
public class Allele {
    private ArrayList<Gene<?>> genes;

    /**
     * Creates a new Allele object from the genes given.
     * @param genes -- A vector of type Gene<?>.
     */
    public Allele(ArrayList<Gene<?>> genes) {
        this.genes = genes;
    }

    /**
     * Returns the genes that this Allele is holding
     * @return -- A vector of type Gene<?> of the genes in the allele.
     */
    public ArrayList<Gene<?>> getGenes() {
        return genes;
    }

    /**
     * Sets the genes that this Allele will hold.
     * @param genes -- A vector of Gene<?>
     */
    public void setGenes(ArrayList<Gene<?>> genes) {
        this.genes = genes;
    }

    /**
     * Combines two Gene Vectors and returns a resulting Gene Vector
     * where the elements of g2 are concatinated with the elemens of g1.
     * @param g1 -- A gene vector that forms the first part of the return vector
     * @param g2 -- A gene vector that forms the last part of the return vector
     * @return -- A gene vector with the elements of g1 and g2 combined.
     */
    public static ArrayList<Gene<?>> Combine(ArrayList<Gene<?>> g1, ArrayList<Gene<?>> g2) {
        ArrayList<Gene<?>> v = new ArrayList<Gene<?>>();
        int size = (g1.size() > g2.size()) ? g1.size() : g2.size();

        while(size > 0) {
            try {
                v.add(0, g1.remove(g1.size() - 1));
                v.add(g2.remove(0));
            } catch(ArrayIndexOutOfBoundsException aioobe) { }
            finally {
                size--;
            }
        }

        return v;
    }

    /**
     * Combines all the allele objects into one gene vector. Example:
     * A[0] = g1, g2, g3
     * A[1] = g4, g5, g6
     * A[2] = g7, g8
     * Then the result would be: g1, g2, g3, g4, g5, g6, g7, g8
     * @param a -- A vector of alleles to be combined
     * @return -- A gene vector of all the genes in the alleles.
     */
    public static ArrayList<Gene<?>> CombineAll(ArrayList<Allele> a) {
        ArrayList<Gene<?>> v = new ArrayList<Gene<?>>();
        int numAlleles = a.size();

        for(int i=0; i<numAlleles; i++) {
            v = Allele.Combine(v, a.get(i).getGenes());
        }

        return v;
    }
}
